/**
 * \file ping.c
 * \brief Main file ping
 * \author Pierre Neumann / Julien Meutelet
 * \version 0.1
 * \date 20 decembre 2013
 *
 * Fonction main du ping
 *
 */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>
#include <arpa/inet.h>

#include "ping.h"
#include "ping_icmp.h"
#include "ping_udp.h"
#include "ping_tcp.h"
#include "packet_utils.h"
#include "addr_utils.h"

char* protocole = "icmp";
int UDP_PORT = 33434;
int TCP_PORT = 80;
int TTL = 255;
int TIMEOUT = 5;
int INTER_TIME = 1;

int paquets_perdus = 0;  /*!< Nombre de paquet perdus */
int paquets_envoyes = 0; /*!< Taille de l'entête UDP */

bool verbose=true;
 
int main(int argc, char **argv){

	if((argc < 2) || (argc % 2 != 0)){
	show_usages();
	exit(-1);

    	}

	int i=0;
	int opt=0;
	//Gestion des arguments
	for(i=1;i<argc-1;++i){
		if(opt==0)
			if(argv[i][0] == '-')
				{
					if(argv[i][1]=='r')
						opt=1;
					else if(argv[i][1]=='p')
						opt=2;
					else if(argv[i][1]=='t')
						opt=3;
					else if(argv[i][1]=='m')
						opt=4;
					else if(argv[i][1]=='i')
						opt=5;
					else if(argv[i][1]=='v')
						opt=6;
					else show_usages();
				}
			else show_usages();
		else if(argv[i][0] == '-'){
			show_usages();
			}
		else if(opt==1){
			protocole=argv[i];
			opt=0;
			}
		else if(opt==2){
			UDP_PORT=atoi(argv[i]);
			TCP_PORT=atoi(argv[i]);
			opt=0;
			}
		else if(opt==3){
			TTL=atoi(argv[i]);
			opt=0;
			}
		else if(opt==4){
			TIMEOUT=atoi(argv[i]);
			opt=0;
			}
		else if(opt==5){
			INTER_TIME=atoi(argv[i]);
			opt=0;
			}
		else if(opt==6){
			if(argv[i][0]=='f')
				verbose=false;
			opt=0;
			}

	}
	char* addr;
	if(inet_addr(argv[argc-1]) != INADDR_NONE) addr = argv[argc-1];
	else addr = get_first_ip_by_hostname(argv[argc-1]);
	if(addr == NULL){
		printf("Adresse non valide\n");
		exit(1);
	}
	struct ping_result *res = NULL;
	//Envoi de ping en boucle
	while(1){
		res=NULL;
		if(argc==2 || strcmp(protocole,"icmp") == 0){
			res = ping_icmp(addr,TTL,TIMEOUT);
			printf("%s %i %i\n",addr,TTL,TIMEOUT);
		}
		else if(strcmp(protocole,"udp") == 0){
			res = ping_udp(addr,UDP_PORT,TTL,TIMEOUT);
		
		}
		else if(strcmp(protocole,"tcp") == 0){
			res = ping_tcp(addr,TCP_PORT,TTL,TIMEOUT);
		}
		else{	
			exit(1);
		}
		++paquets_envoyes;
		if(res!=NULL) print_ping_result(res);//verbose
		else{
			++paquets_perdus;
			printf("Packet perdu\n");
		}
		if(verbose)
			printf("envoyes:%i perdus:%i\n",paquets_envoyes,paquets_perdus);
		sleep(INTER_TIME);
	}
	if(res!=NULL)free(res);
        return 0;
}

/**
 * \fn show_usages()
 * \brief Aide à l'utilisation
 *
 * \return Rien.
 */
void show_usages(){
	printf("Utilisation: ping [options] addr\n");
	printf("Les options sont les suivantes :\n");
	printf("-r : choix du protocole : -r udp/tcp/icmp    (par defaut : icmp)\n");
	printf("-p : choix du port      : -p numero_de_port  (par defaut : udp:33434 et tcp:80)\n");
	printf("-t : choix du TTL :       -t nombre_de_saut  (par defaut : 255)\n");
	printf("-m : choix du temps avant timeout en seconde (par defaut : 2 seconde)\n");
	printf("-i : temps intersonde   : -i temps en seconde(par defaut : 1 secondes)\n");
	printf("-v : aucun print	: -v false           (par default : true)\n");
	printf("\nexample -> ping -r tcp -t 15 -m 10 -i 0 -v false 10.0.0.1\n==sonde tcp vers 10.0.0.1 sur le port par defaut(80) avec TTL de 15 et sans attente entre les envois. Un paquet sera considere perdu apres une attente de 10 secondes et aucun print n'apparaitra\n");
}
